%%% -------------------------------------------------------------------
%%% Author  : 77
%%% Description :
%%%
%%% Created : 2011-7-2
%%% -------------------------------------------------------------------
-module(node_server).

-behaviour(gen_server).
%% --------------------------------------------------------------------
%% Include files
%% --------------------------------------------------------------------

%% --------------------------------------------------------------------
%% External exports
-export([start_link/0, stop/0, sendmsg/1]).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-record(state, {}).

%% ====================================================================
%% External functions
%% ====================================================================
start_link() ->
    gen_server:start_link({local,?MODULE}, ?MODULE, [], []).

stop() ->
	gen_server:cast(?MODULE, stop).

sendmsg(Request) ->
	gen_server:call(?MODULE, Request).


%% ====================================================================
%% Server functions
%% ====================================================================

%% --------------------------------------------------------------------
%% Function: init/1
%% Description: Initiates the server
%% Returns: {ok, State}          |
%%          {ok, State, Timeout} |
%%          ignore               |
%%          {stop, Reason}
%% --------------------------------------------------------------------
init([]) ->
    {ok, {initState, ets:new(runningTaskTable, [])}}.

%% --------------------------------------------------------------------
%% Function: handle_call/3
%% Description: Handling call messages
%% Returns: {reply, Reply, State}          |
%%          {reply, Reply, State, Timeout} |
%%          {noreply, State}               |
%%          {noreply, State, Timeout}      |
%%          {stop, Reason, Reply, State}   | (terminate/2 is called)
%%          {stop, Reason, State}            (terminate/2 is called)
%% --------------------------------------------------------------------
handle_call(Request, From, {State, RunningTaskTable}) ->
	io:format("handle_call (~p)~n", [Request]),
    {Pid, _} = spawn_monitor(fun() -> 
					  execute_task(From, Request, RunningTaskTable) end ),
	io:format("handle_call 2 (~p)~n", [Pid]),
	ets:insert(RunningTaskTable, {Pid, From, Request}),
	%io:format("handle_call 3 (~p)~n", [Request]),
    {noreply, {State, RunningTaskTable}}.

execute_task(From, Request, RunnintTaskTable) ->
	io:format("execute_task (~p)~n", [Request]),
	Response = case Request of
		{fetch_node_resource,_} ->
			%{ok,{"TestHostName","127.0.0.0",4,200,200,50,50}};
			D = os:cmd("bash /root/xiyoucloud/NodeController/priv/script/get_node_resource.sh") -- "\r\n",
			io:format("os:cmd return ~p ~n", [D]),
			case io_lib:fread("~s~s~d~d~d~d~d", D) of 
				{ok,ParseRes,_} ->
%					[ParseRes1] = ParseRes,
%					{ok,ParseRes};
					[HostName,IpAddr,VcpuCount,StorageSize,MemorySize,FreeStorageSize,FreeMemorySize] = ParseRes,
					Resource = {HostName,IpAddr,VcpuCount,StorageSize,MemorySize,FreeStorageSize,FreeMemorySize},
					{ok,Resource};
			    _ -> 
                     {error,resource_unkown}
			end;
	    {create_vm,Content} ->
			%%{Vm_id,VcpuCount,MemSize,DiskSize,Ipaddr,VncPort,VncPass} = Content,
			%%{VmId,VcpuCount,MemSize,DiskSize,IpAddr} = Content,
			{VcpuCount,MemSize,DiskSize,IpAddr,MacAddr,VncPass,VncPort,VmUser,VmUserPass,VmId} = Content,
			io:format("create vm request  ~p ~n", [Content]),
			Params = lists:concat(["bash /root/xiyoucloud/NodeController/priv/script/create_vm.sh ",
									integer_to_list(VcpuCount)," ",
									integer_to_list(MemSize), " ",
									integer_to_list(DiskSize)," ",
									IpAddr," ",
									MacAddr," ",
									VncPass," ",
									integer_to_list(VncPort)," ",
									VmUser," ",
									VmUserPass," ",
									integer_to_list(VmId)]),
			io:format("~p~n", [Params]),
			D = os:cmd(Params) -- "\r\n",
%			D = os:cmd("bash create_vm.sh") -- "\r\n",
			io:format("cmd result  ~p ~n", [D]),
			if 
			    D == "FAIL" ->
				  error;
			    D == "SUCC" ->
				  ok
		    end;
	    {stop_vm,Content} ->
			{VmId} = Content,
			io:format("stop vm request ~p ~n", [Content]),
			Params = lists:concat(["bash /root/xiyoucloud/NodeController/priv/script/stop_vm.sh ",
									integer_to_list(VmId)]),
			io:format("~p~n", [Params]),
			Result = os:cmd(Params) -- "\r\n",
			io:format("cmd result ~p~n", [Result]),
			if
				Result == "FAIL" ->
					error;
				Result == "SUCC" ->
					ok
			end;
	    {destroy_vm,Content} ->
			{VmId} = Content,
			io:format("destroy vm request ~p ~n", [Content]),
			Params = lists:concat(["bash /root/xiyoucloud/NodeController/priv/script/destroy_vm.sh ",
									integer_to_list(VmId)]),
			io:format("~p~n", [Params]),
			Result = os:cmd(Params) -- "\r\n",
			io:format("cmd result ~p~n", [Result]),
			if
				Result == "FAIL" ->
					error;
				Result == "SUCC" ->
					ok
			end;

	    {start_vm,Content} ->
			%%{Vm_id,VcpuCount,MemSize,DiskSize,Ipaddr,VncPort,VncPass} = Content,
			%%{Vm_id,VcpuCount,MemSize,DiskSize,Ipaddr,VncPort,VncPass,Passwd} new_update
			{VmId} = Content,
			io:format("start vm request  ~p ~n", [Content]),
%			Params = integer_to_list(VmId),
			Params = lists:concat(["bash /root/xiyoucloud/NodeController/priv/script/start_vm.sh ", VmId]),
			io:format("Params  ~p ~n", [Params]),
%			D = os:cmd("start_vm.sh" ++ " " ++ Params),
			D = os:cmd(Params) -- "\r\n",
		    io:format("cmd result  ~p ~n", [D]),
			if 
			    D == "FAIL" ->
				  error;
			    D == "SUCC" ->
				  ok
		    end;

		{fuck} ->
			{ok, fuck};
		
		Other ->
			{ok, unkownRequest}
	end,
	io:format("delete (~p)~n", [self()]),
	%ets:delete(RunnintTaskTable, self()),
	gen_server:reply(From, Response).



%% --------------------------------------------------------------------
%% Function: handle_cast/2
%% Description: Handling cast messages
%% Returns: {noreply, State}          |
%%          {noreply, State, Timeout} |
%%          {stop, Reason, State}            (terminate/2 is called)
%% --------------------------------------------------------------------
handle_cast(Msg, State) ->
    {noreply, State}.


%% --------------------------------------------------------------------
%% Function: handle_info/2
%% Description: Handling all non call/cast messages
%% Returns: {noreply, State}          |
%%          {noreply, State, Timeout} |
%%          {stop, Reason, State}            (terminate/2 is called)
%% --------------------------------------------------------------------
handle_info({'EXIT', Pid, Reason}, {State, RunnintTaskTable}) ->
	io:format("(~p) exit with (~p)~n", [Pid, Reason]),
	Result = ets:lookup(RunnintTaskTable, Pid),
	case Result of 
		[] ->
			{noreply, {State, RunnintTaskTable}};
		{From, Request} ->
			gen_server:reply(From, failed)
	end;

handle_info(Info, State) ->
    {noreply, State}.

%% --------------------------------------------------------------------
%% Function: terminate/2
%% Description: Shutdown the server
%% Returns: any (ignored by gen_server)
%% --------------------------------------------------------------------
terminate(Reason, State) ->
    ok.

%% --------------------------------------------------------------------
%% Func: code_change/3
%% Purpose: Convert process state when code is changed
%% Returns: {ok, NewState}
%% --------------------------------------------------------------------
code_change(OldVsn, State, Extra) ->
    {ok, State}.

%% --------------------------------------------------------------------
%%% Internal functions
%% --------------------------------------------------------------------

